package com.zycfc.zsf.boot.swagger2;

import springfox.documentation.swagger2.annotations.*;
import org.springframework.context.annotation.*;
import org.springframework.boot.context.properties.*;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.beans.factory.config.*;
import javax.annotation.*;
import springfox.documentation.spi.*;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import springfox.documentation.service.*;
import springfox.documentation.spring.web.plugins.*;
import springfox.documentation.builders.*;
import springfox.documentation.schema.*;
import com.zycfc.zsf.boot.exception.type.*;
import org.springframework.beans.*;
import springfox.documentation.*;
import com.google.common.base.*;
import org.slf4j.*;

@EnableSwagger2
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties({ SwaggerProperties.class })
@ConditionalOnProperty(value = { "zsf.boot.swagger2.enabled" }, matchIfMissing = true)
public class SwaggerAutoConfiguration implements BeanFactoryAware
{
    private static final Logger log;
    private static final String splitor = ",";
    private BeanFactory beanFactory;
    @Autowired
    private SwaggerProperties swaggerProperties;
    
    @PostConstruct
    public List<Docket> createRestApi() {
        final ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory)this.beanFactory;
        if (this.swaggerProperties.getDocket().isEmpty()) {
            configurableBeanFactory.registerSingleton("defaultDocket", (Object)this.defaultDocket());
            return null;
        }
        final List<Docket> docketList = new LinkedList<Docket>();
        for (final String groupName : this.swaggerProperties.getDocket().keySet()) {
            final SwaggerProperties.DocketInfo docketInfo = this.swaggerProperties.getDocket().get(groupName);
            final Docket docket = this.buildDocket(groupName, docketInfo);
            configurableBeanFactory.registerSingleton(groupName, (Object)docket);
            docketList.add(docket);
        }
        SwaggerAutoConfiguration.log.debug("^_^swagger2\u7ec4\u4ef6\u52a0\u8f7d\u6210\u529f^_^");
        return docketList;
    }
    
    private Docket defaultDocket() {
        final ApiInfo apiInfo = new ApiInfoBuilder().title(this.swaggerProperties.getTitle()).description(this.swaggerProperties.getDescription()).version(this.swaggerProperties.getVersion()).license(this.swaggerProperties.getLicense()).licenseUrl(this.swaggerProperties.getLicenseUrl()).contact(new Contact(this.swaggerProperties.getContact().getName(), this.swaggerProperties.getContact().getUrl(), this.swaggerProperties.getContact().getEmail())).termsOfServiceUrl(this.swaggerProperties.getTermsOfServiceUrl()).build();
        if (this.swaggerProperties.getBasePath().isEmpty()) {
            this.swaggerProperties.getBasePath().add("/**");
        }
        final List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
        for (final String path : this.swaggerProperties.getBasePath()) {
            basePath.add((Predicate<String>)PathSelectors.ant(path));
        }
        final List<Predicate<String>> excludePath = new ArrayList<Predicate<String>>();
        for (final String path2 : this.swaggerProperties.getExcludePath()) {
            excludePath.add((Predicate<String>)PathSelectors.ant(path2));
        }
        Set<String> produces = this.swaggerProperties.getProduces();
        if (null == produces) {
            produces = new LinkedHashSet<String>();
        }
        if (produces.isEmpty()) {
            produces.add("application/json;charset=UTF-8");
        }
        final List<ResponseMessage> responseMessages = this.getResponseMessages();
        final ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(this.swaggerProperties.getHost()).apiInfo(apiInfo).useDefaultResponseMessages(false).globalResponseMessage(RequestMethod.GET, (List)responseMessages).globalResponseMessage(RequestMethod.POST, (List)responseMessages).produces((Set)produces).select();
        final String basePackage = this.swaggerProperties.getBasePackage();
        if (null != basePackage && basePackage.length() > 0) {
            builder.apis((Predicate)basePackage(basePackage));
        }
        final Docket docket = builder.paths(Predicates.and(Predicates.not(Predicates.or((Iterable)excludePath)), Predicates.or((Iterable)basePath))).build();
        return docket;
    }
    
    private Docket buildDocket(final String groupName, final SwaggerProperties.DocketInfo docketInfo) {
        final ApiInfo apiInfo = new ApiInfoBuilder().title(docketInfo.getTitle().isEmpty() ? this.swaggerProperties.getTitle() : docketInfo.getTitle()).description(docketInfo.getDescription().isEmpty() ? this.swaggerProperties.getDescription() : docketInfo.getDescription()).version(docketInfo.getVersion().isEmpty() ? this.swaggerProperties.getVersion() : docketInfo.getVersion()).license(docketInfo.getLicense().isEmpty() ? this.swaggerProperties.getLicense() : docketInfo.getLicense()).licenseUrl(docketInfo.getLicenseUrl().isEmpty() ? this.swaggerProperties.getLicenseUrl() : docketInfo.getLicenseUrl()).contact(new Contact(docketInfo.getContact().getName().isEmpty() ? this.swaggerProperties.getContact().getName() : docketInfo.getContact().getName(), docketInfo.getContact().getUrl().isEmpty() ? this.swaggerProperties.getContact().getUrl() : docketInfo.getContact().getUrl(), docketInfo.getContact().getEmail().isEmpty() ? this.swaggerProperties.getContact().getEmail() : docketInfo.getContact().getEmail())).termsOfServiceUrl(docketInfo.getTermsOfServiceUrl().isEmpty() ? this.swaggerProperties.getTermsOfServiceUrl() : docketInfo.getTermsOfServiceUrl()).build();
        if (docketInfo.getBasePath().isEmpty()) {
            docketInfo.getBasePath().add("/**");
        }
        final List<Predicate<String>> basePath = new ArrayList<Predicate<String>>();
        for (final String path : docketInfo.getBasePath()) {
            basePath.add((Predicate<String>)PathSelectors.ant(path));
        }
        final List<Predicate<String>> excludePath = new ArrayList<Predicate<String>>();
        for (final String path2 : docketInfo.getExcludePath()) {
            excludePath.add((Predicate<String>)PathSelectors.ant(path2));
        }
        Set<String> produces = this.swaggerProperties.getProduces();
        if (null == produces) {
            produces = docketInfo.getProduces();
        }
        if (null == produces) {
            produces = new LinkedHashSet<String>();
        }
        final List<ResponseMessage> responseMessages = this.getResponseMessages();
        final ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2).host(this.swaggerProperties.getHost()).apiInfo(apiInfo).useDefaultResponseMessages(false).globalResponseMessage(RequestMethod.GET, (List)responseMessages).globalResponseMessage(RequestMethod.POST, (List)responseMessages).produces((Set)produces).groupName(groupName).select();
        final String basePackage = docketInfo.getBasePackage();
        if (null != basePackage && basePackage.length() > 0) {
            builder.apis(RequestHandlerSelectors.basePackage(basePackage));
        }
        final Docket docket = builder.paths(Predicates.and(Predicates.not(Predicates.or((Iterable)excludePath)), Predicates.or((Iterable)basePath))).build();
        return docket;
    }
    
    private List<ResponseMessage> getResponseMessages() {
        final List<ResponseMessage> responseMessages = new ArrayList<ResponseMessage>();
        responseMessages.add(new ResponseMessageBuilder().code(0).message("7\u4e2a0\u64cd\u4f5c\u6210\u529f").responseModel((ModelReference)null).build());
        for (final ExceptionCode code : ExceptionCode.values()) {
            responseMessages.add(new ResponseMessageBuilder().code(Integer.parseInt(code.getValue())).message(code.getMessage()).responseModel((ModelReference)null).build());
        }
        return responseMessages;
    }
    
    public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    
    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return (Predicate<RequestHandler>)(input -> (boolean)declaringClass(input).transform((Function)handlerPackage(basePackage)).or((Object)true));
    }
    
    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return (Function<Class<?>, Boolean>)(input -> {
            for (final String strPackage : basePackage.split(",")) {
                final boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        });
    }
    
    private static Optional<? extends Class<?>> declaringClass(final RequestHandler input) {
        return (Optional<? extends Class<?>>)Optional.fromNullable((Object)input.declaringClass());
    }
    
    static {
        log = LoggerFactory.getLogger((Class)SwaggerAutoConfiguration.class);
    }
}
